package Client;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.Dialog.ModalityType;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.sql.SQLException;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import Client.excepciones.IncorrectCodeException;
import Client.excepciones.UnexpectedErrorException;

import server.bd.GestionDatos;
import util.SocketManager;

/**
 * Clase de ventana principal de la aplicacion cliente.
 * @author inlacou
 *
 */
public class JFrameCliente extends JFrame{

	static java.util.Properties properties = new java.util.Properties();
	static final String path = "/home/leyer/config.xml";
	static boolean loaded = false;
	private final Image icon = new ImageIcon(getClass().getResource("Gestion_Trenes_icono.png")).getImage();

	private JPanelCliente jPCliente;
	private JMenuBarCliente mb;

	private boolean conectado;
	private ClienteTCP cTCP;


	/**
	 * Constructor de la clase JFrameCliente
	 */
	public JFrameCliente() {
		super("Aplicacion Cliente");

		//Inicializacion de variables simples.
		mb = new JMenuBarCliente(this);
		jPCliente = new JPanelCliente(cTCP, this);
		conectado = false;

		//Propiedades
		load();

	}

	/**
	 * Funcion que anyade los componentes al JFrame
	 */
	private void addComponents(){
		this.getContentPane().add(jPCliente);
		jPCliente.setComponentsEnabled(false);
		this.setJMenuBar(mb);
	}

	/**
	 * Funcion para pasar a la ventana de login y para realizar el cambio en el JFrame despues de logearse.
	 */
	protected void conectar(){
		if(conectado){
			//Si se llama a este metodo pero no esta conectado, se cambia el texto del menuItem correspondiente
			//para que permita la desconexion.
			mb.disconnect();
		} else {
			//Se crea la ventana con la que hacer el login.
			JDialogUsuario JDC = new JDialogUsuario(this, ModalityType.APPLICATION_MODAL);
			//Hacemos visible la ventana.
			JDC.setVisible(true);
		}
		//Segun si esta conectado o no, habilita o deshabilita los botones.
		jPCliente.setComponentsEnabled(conectado);
	}

	/**
	 * Metodo que se llama cuando el usuario se conecta. Cambia el estado del boolean "conectado" a true y el texto
	 * del menuItem "connect" a "Disconnect".
	 */
	protected void conectado(){
		conectado = true;
		mb.disconnect();
	}

	/**
	 * Funcion para realizar los cambios pertinentes al JFrame cuando el usuario se desconecta.
	 */
	protected void desconectar(){
		conectado = false;
		mb.connect();
		jPCliente.setComponentsEnabled(conectado);
	}

	/**
	 * Metodo que carga las propiedades de la ventana, como el tama�o, el icono...
	 */
	public void load(){
		//XXX carga de la configuracion desde un archivo.
		Dimension minimumSize = new Dimension(280, 380);

		//Insercion de componentes.
		addComponents();
		
		this.addWindowListener(new WindowListener() {
			@Override
			public void windowOpened(WindowEvent arg0) {
				mb.requestFocus();
			}
			@Override
			public void windowIconified(WindowEvent arg0) {
				mb.requestFocus();
			}
			@Override
			public void windowDeiconified(WindowEvent arg0) {
				mb.requestFocus();
			}
			@Override
			public void windowDeactivated(WindowEvent arg0) {
			}
			@Override
			public void windowClosing(WindowEvent arg0) {
				try {
					cerrarConexion();
					System.exit(0);
				} catch (IOException e1) {
				} catch (UnexpectedErrorException e) {
				} catch (IncorrectCodeException e2) {
				}
			}
			@Override
			public void windowClosed(WindowEvent arg0) {
			}
			@Override
			public void windowActivated(WindowEvent arg0) {
				mb.requestFocus();
			}
		});
		
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setSize(minimumSize);
		this.setMinimumSize(minimumSize);
		this.setIconImage(icon);
	}

	/**
	 * Metodo que redibuja la ventana. Determina un nuevo tama�o segun los elementos actuales del JFrame,
	 * y llama a los metodos repaint() de los componentes hijo que deben repintarse.
	 */
	public void repaint(){
		try{
			mb.actualizar(this); //Llamamos al metodo actualizar(Component) de la clase menuBar, que actualizara la fuente, el color de letra y el fondo del componente introducido por parametro.
			jPCliente.repaint(); //Redibujamos el panel jPCliente.
			//A continuacion cambiamos el tama�o de la ventana en funcion del tama�o de los botones, el tama�o de letra... Aun esta pobremente optimizado.
			this.setMinimumSize(new Dimension(this.getSize().width+this.getFont().getSize()/16, 
					20+(int)Math.floor(jPCliente.getButton(1).getHeight()*jPCliente.nb*this.getFont().getSize()/12)));
			this.setSize(new Dimension((int)Math.floor(this.getSize().width+1.4*this.getFont().getSize()/16), 
					20+(int)Math.floor(jPCliente.getButton(1).getHeight()*jPCliente.nb*1.1*this.getFont().getSize()/12)));
			
		}catch(NullPointerException npe){
			//Dado que solo generara esta excepcion una vez al inicio de la aplicacion,
			//simplemente queremos que la ignore. Asi que no hace nada.
		}
	}
	
	/**
	 * Metodo que determina la variable ClienteTCP a utilizar.
	 * @param clienteTCP
	 */
	protected void setCTCP(ClienteTCP clienteTCP){
		cTCP = clienteTCP;
		jPCliente.setTCP(clienteTCP);
	}
	
	/**
	 * Metodo para cambiar el mensaje del label para tal uso en la clase JPanelCliente.
	 * @param mensaje
	 */
	protected void setMensaje(String mensaje){
		jPCliente.setMensaje(mensaje);
	}
	
	/**
	 * Metodo para cerrar la conexion con el servidor.
	 * @return true si se ha desconectado (o si ya estaba desconectado), false si no.
	 * @throws IOException
	 * @throws IncorrectCodeException
	 * @throws UnexpectedErrorException
	 */
	protected boolean cerrarConexion() throws IOException, IncorrectCodeException, UnexpectedErrorException{
		if(conectado){
				if(cTCP.cerrar()){
					return true;
				}else{
					return false;
				}
		}
		return true;
	}

	/**
	 * Metodo main de la aplicacion.
	 * @param args
	 */
	public static void main(String[]args) {
		JFrameCliente v = new JFrameCliente();
		v.setLocation(250, 100);
		v.setVisible(true);
	}

}